import java.applet.*;
import java.awt.*;
import java.net.*;
import javax.media.*;

import javax.media.Manager;

/**
 * JMFApplet uses Java Media Framework Player functionality
 * to load and play audio or video multimedia files or streams.
 * <P>
 * JMFApplet is compliant with JMF Beta spec, v0.96, Jan 1997.
 * 
 * @author Bill Day <bday@sgi.com>
 * @version 1.0
 * @see java.media.Player
**/
public class JMFApplet extends Applet implements ControllerListener {

    boolean eomReached = false;
    boolean realized = false;   
    URL myURL = null;
    Player myPlayer = null; 
    Label status = null;
    Component myVisual = null;
    Component myControls = null;
    Panel visualPanel = null;

    /**
     * Initialize JMFApplet, laying out the interface, realizing the
     * player, prefetching the asset, and in general readying for playback.
    **/
    public void init() {
        super.init();
        
        // Specify AWT Layout Manager and pack status message into
        // it to tell user we are loading.
        setLayout (new BorderLayout());
        status = new Label("Loading media asset...please wait.",Label.CENTER);
        add("North",status);
        validate(); 
        
        // Load URL from web page.
	    String asset = getParameter("ASSET");
	    
	    
	    // Check that we have a valid URL and create URL object to hold it.
        if (asset.equals("")) {
           status.setText("*Please specify one URL to play*");
        } else {
           try {
              myURL = new URL(getDocumentBase(),asset);
           } catch (MalformedURLException e) {
              status.setText("*Please specify a valid URL to play*");
           }   
        }
        try {
           myPlayer = Manager.createPlayer(myURL);
        } catch (java.io.IOException e) {
           status.setText("IOException...exiting.");
           System.exit(1);
        } catch (NoPlayerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        if (myPlayer == null) {
            status.setText("myPlayer is null...exiting.");
            System.exit(1);
        }
        //Register JMFApplet as an observer of myPlayer.
        myPlayer.addControllerListener(this);
        
        // The Player.realize() method is non-blocking.  However, we
        // need to be certain we have a realized player before 
        // continuing, so we implement and call our blockingRealize
        // method to ensure this.
        blockingRealize();
        
        // Now that we have a Realized player, we can get the
        // VisualComponent and ControlPanelComponent and pack
        // them into our applet.
        myVisual = myPlayer.getVisualComponent();
        if (myVisual != null) {
           // In order to ensure that the VisualComponent
           // is not resized by BorderLayout, I nest it
           // within visualPanel using FlowLayout.
           visualPanel = new Panel();
           visualPanel.setLayout(new FlowLayout()); 
           visualPanel.add(myVisual);
           add("Center",visualPanel);
        } else {
           remove(status);
           add("Center",status);
           status.setText("No VisualComponent available.");
        }
        myControls = myPlayer.getControlPanelComponent();
        if (myControls != null) {
           add("South",myControls);
        }
        validate();
        
        // Prefetch asset and we are ready to being playback!
        myPlayer.prefetch();
        status.setText("JMF Player is ready to play "+asset);
    }
     
    /**
     * Override the default applet stop method to call myPlayer.stop()
     * and myPlayer.deallocate() so that we properly free up resources
     * if someone exits this page in their browser.
    **/
    public void stop() {
       myPlayer.stop();
       myPlayer.deallocate();
    }
     
    /**
     * Since realize() is non-blocking, I've implemented this method
     * as a wrapper to do blocking realization.  It can be called by
     * any method that needs to be certain that realize has occured
     * before preceeding.
    **/
    public synchronized void blockingRealize() {
       myPlayer.realize();
       while (!realized) {
          try {
             wait();
          } catch (java.lang.InterruptedException e) {
             status.setText("Interrupted while waiting on realize...exiting.");
             System.exit(1);
          }
       }
    }

    /**
     * The controllerUpdate method is from java.media.ControllerListener, 
     * and deals with events generated by myPlayer.  This allows JMFApplet
     * to react to myPlayer events.
    **/
    public synchronized void controllerUpdate (ControllerEvent event) {
        // Print to standard output the type of event we received.
        System.out.println("myPlayer generated "+event.toString());
        // If the event was a RealizeCompleteEvent or EndofMediaEvent,
        // we want to react to it as below.
        if (event instanceof RealizeCompleteEvent) {
           realized = true;
           notify();
        } else if (event instanceof EndOfMediaEvent) {
           eomReached = true;
        }
    }
}

